Skip to content

선의 통과를 감지하기

움직이는 스프라이트에서 만든 맵에 선의 통과를 감지하는 기능을 추가해보겠습니다. 선의 통과를 감지하기 위해서는 DetectLineCrossing Hook과 SensorLine Sprite를 사용합니다.

만들어볼 맵은 다음과 같습니다. 아래 맵은 브라우저에서 Stadium을 통해 직접 그려졌습니다.

아직 선을 통과하지 않았습니다.

이전 코드

움직이는 스프라이트에서 만든 코드는 다음과 같습니다.

js
import { Stadium, ImageSprite, Animate } from "@rycont/stadium";

const element = document.getElementById("stadium");

const stadium = new Stadium(element, {
  width: 800,
  height: 600,
});

const src = "https://picsum.photos/200";

const size = { width: 80, height: 80 };
const position = { left: 140, top: 240 };

const image = new ImageSprite({ src, size, position });

const animate = new Animate();
image.use([animate]);

stadium.add(image);

animate.moveBy(80, 0, 3000);
animate.moveTo(120, 120, 2000);

감지할 선 만들기

선을 그리기 위해서는 시작점과 끝점을 지정해야 합니다. Stadium에서는 lefttop을 사용하여 위치를 지정합니다. left는 왼쪽에서부터의 거리를, top은 위쪽에서부터의 거리를 나타냅니다.

js
const points = {
  p1: { left: 0, top: 300 }, // 시작점
  p2: { left: 500, top: 0 }, // 끝점
};

선을 만들기 위해서는 SensorLine 스프라이트를 사용합니다.

js
const line = new SensorLine(points);

Stadium에 선을 추가합니다.

js
stadium.add(line);

중간 코드

js
const points = { p1, p2 };
const line = new SensorLine(points);

stadium.add(line);

DetectLineCrossing Hook 설정하기

선의 통과를 감지하기 위해서는 DetectLineCrossing Hook을 사용합니다.

js
const detector = new DetectLineCrossing({});

DetectLineCrossing가 감지할 선을 지정합니다. [instance].targetTag 태그가 지정된 SensorLine만 감지할 수 있습니다.

SensorLinetagsdetector.targetTag를 추가합니다.

js
line.tags.push(detector.targetTag);

detectLineCrossing를 이미지 스프라이트에 추가합니다.

js
image.use([animate]); 
image.use([detector, animate]); 

선의 통과를 감지하는 이벤트 구독하기

DetectLineCrossingSensorLine을 관통하는 애니메이션이 발생할 때 crossed 이벤트를 생성합니다.

DANGER

관통하는 애니메이션이 발생하는 것이 아니라, 관통하는 애니메이션이 발생할 때 이벤트가 발생합니다.

DetectLineCrossingpubsub을 사용하여 crossed 이벤트를 구독합니다.

js
detector.pubsub.sub("crossed", () => {
  alert("선을 통과합니다!");
});

전체 코드

js
import {
  Stadium,
  SensorLine,
  ImageSprite,
  Animate,
  DetectLineCrossing,
} from "@rycont/stadium";

const element = document.getElementById("stadium");

const stadium = new Stadium(element, {
  width: 800,
  height: 600,
});

const src = "https://picsum.photos/200";

const size = { width: 80, height: 80 };
const position = { left: 140, top: 240 };

const image = new ImageSprite({ src, size, position });

const animate = new Animate();

stadium.add(image);

const points = {
  p1: { left: 0, top: 300 },
  p2: { left: 500, top: 0 },
};
const line = new SensorLine(points);

stadium.add(line);

const detector = new DetectLineCrossing();
line.tags.push(detector.targetTag);
image.use([animate, detector]);

animate.moveBy(80, 0, 3000);
animate.moveTo(120, 120, 2000);

detector.pubsub.sub("crossed", () => {
  alert("선을 통과합니다!");
});